# 数据库链接
import configparser
import os
import sys
import time
import traceback
import warnings

import pymysql
from xjlibrary.our_file_dir import BaseDir

curPath = os.path.join(BaseDir.get_file_dir_absolute(__file__), "mysql.ini")


def MySqlDbConnect(cur_path, dbConfigFileName=None, encoding='utf-8', cursorclass=None):
    """
    连接数据库 通过读取配置文件连接,如果读取配置文件 失败  返回None
    cursorclass=pymysql.cursors.SSDictCursor,
    :return:
    """
    if not cur_path:
        warnings.warn("MajorDbConnect config path err,get default path config,That may be a mistake")
        global curPath
    else:
        curPath = cur_path
    cf = configparser.ConfigParser()
    if dbConfigFileName:
        curPath = os.path.join(curPath, dbConfigFileName)
    try:
        cf.read(curPath, encoding=encoding)
    except:
        print('读取配置失败:' + traceback.format_exc())
        sys.exit(-1)
    if cf:
        db_host = cf.get('db', 'db_host')
        db_user = cf.get('db', 'db_user')
        db_pw = cf.get('db', 'db_pw')
        db_port = cf.get('db', 'db_port')
        db_name = cf.get('db', 'db_name')
        db_charset = cf.get('db', 'db_charset')
        print(db_host)
        print(db_user)
        print(db_pw)
        print(db_port)
        print(db_name)
        print(db_charset)

        try:
            if cursorclass:
                # 这个是为了兼容cursorclass
                conn = pymysql.connect(host=db_host, port=int(db_port), user=db_user, passwd=db_pw, db=db_name,
                                       charset=db_charset, cursorclass=cursorclass)
            else:
                conn = pymysql.connect(host=db_host, port=int(db_port), user=db_user, passwd=db_pw, db=db_name,
                                       charset=db_charset)
        except:
            # 有可能因为网络波动无法连接 这里休眠10秒重连一次  如果还是失败就放弃
            time.sleep(10)
            if cursorclass:
                conn = pymysql.connect(host=db_host, port=int(db_port), user=db_user, passwd=db_pw, db=db_name,
                                       charset=db_charset, cursorclass=cursorclass)
            else:
                conn = pymysql.connect(host=db_host, port=int(db_port), user=db_user, passwd=db_pw, db=db_name,
                                       charset=db_charset)
        if conn:
            return conn
    return None


# 更新数据库状态
def ExeSqlList(sSqlList, conn=None, cur_path=None, errExit=False):
    """
    该函数处理一个sql列表 没有返回并将列表置空
    :param sSqlList:
    :return:
    """
    dbMsg = None
    failed_count = success_count = 0
    if not conn and not cur_path:
        raise ValueError("database conn or database config must have to have one")
    if not conn:
        conn = MySqlDbConnect(cur_path)
    if not conn:
        raise AttributeError("mysql conn not exist,please check conn or curpath")
    cur = conn.cursor()

    for sql in sSqlList:
        try:
            print(sql)
            cur.execute(sql)
            success_count += 1
        except:
            conn.commit()
            print('*errSql:' + sql)
            dbMsg = '*updateError:' + traceback.format_exc()
            if errExit:
                print(dbMsg)
                sys.exit(-1)
            failed_count += 1
        if dbMsg:
            print(dbMsg)
            continue
    conn.commit()
    cur.close()
    conn.close()
    return success_count, failed_count


def SelctSqlFromDB(sSql, conn=None, cur_path=None):
    """
    使用sql语句查询并返回结果列表
    :param sql:
    :return:
    """
    if not conn and not cur_path:
        raise ValueError("database conn or database config must have to have one")
    if not conn:
        conn = MySqlDbConnect(cur_path)
    if not conn:
        raise AttributeError("mysql conn not exist,please check conn or curpath")
    cur = conn.cursor()
    try:
        print(sSql)
        cur.execute(sSql)
        rows = cur.fetchall()
        return rows
    except:
        print('* errSql:' + sSql)
        sMsg = '* errSynax:' + traceback.format_exc()
    finally:
        cur.close()
        conn.close()
    if sMsg:
        print(sMsg)
        return None


def SelctSqlFromDBFetchOne(sSql, conn=None, cur_path=None):
    """
    使用sql语句查询并返回结果列表
    :param sql:
    :return:
    """
    if not conn and not cur_path:
        raise ValueError("database conn or database config must have to have one")
    if not conn:
        conn = MySqlDbConnect(cur_path)
    if not conn:
        raise AttributeError("mysql conn not exist,please check conn or curpath")
    cur = conn.cursor()
    try:
        print(sSql)
        cur.execute(sSql)
        rows = cur.fetchone()
        return rows
    except:
        print('* errSql:' + sSql)
        sMsg = '* errSynax:' + traceback.format_exc()
    finally:
        cur.close()
        conn.close()
    if sMsg:
        print(sMsg)
        return None


def ExeSqlToDB(sSql, conn=None, cur_path=None, errExit=False):
    sMsg = None
    if not conn and not cur_path:
        raise ValueError("database conn or database config must have to have one")
    if not conn:
        conn = MySqlDbConnect(cur_path)
    if not conn:
        raise AttributeError("mysql conn not exist,please check conn or curpath")
    cur = conn.cursor()
    try:
        print(sSql)
        rows = cur.execute(sSql)
        conn.commit()
        return True, rows
    except:
        print('* errSql:' + sSql)
        sMsg = '* errSynax:' + traceback.format_exc()
        if errExit:
            print(sMsg)
            sys.exit(-1)
    finally:
        cur.close()
        conn.close()
    if sMsg:
        print(sMsg)
        return False,0


# 更新数据库状态
def ExeSqlMany(sSql, values, conn=None, cur_path=None, errExit=False):
    """
    该函数处理一个sql列表 没有返回并将列表置空
    :param conn:
    :param sSqlList:
    :return:
    """
    if not conn and not cur_path:
        raise ValueError("database conn or database config must have to have one")
    if not conn:
        conn = MySqlDbConnect(cur_path)
    if not conn:
        raise AttributeError("mysql conn not exist,please check conn or curpath")
    cur = conn.cursor()
    try:
        print(sSql)
        cur.executemany(sSql, values)
        conn.commit()
        return True
    except:
        print('*errSql:' + sSql)
        dbMsg = '*updateError:' + traceback.format_exc()
        if errExit:
            print(dbMsg)
            sys.exit(-1)
    finally:
        cur.close()
        conn.close()
    if dbMsg:
        print(dbMsg)
        return False
